package puzzle.masyu2.solver;

import java.util.List;

import puzzle.common.point.Direction;
import puzzle.common.point.Pnt;
import puzzle.common.solver.topology.TrackAnalyzable;
import puzzle.masyu2.data.FlagHelper;
import puzzle.masyu2.data.MasyuBoard;

class MasyuTrackAnalyzable implements TrackAnalyzable {
	private MasyuBoard m_board;
	private int m_index;
	private int m_maxIndex;
	private int[] m_visitFlags;

	public MasyuTrackAnalyzable(MasyuBoard b) {
		m_board = b;
		m_index = 0;
		m_maxIndex = m_board.width * m_board.height;
		m_visitFlags = new int[m_maxIndex];
	}

	public Pnt findNextNode() {
		while (m_index < m_maxIndex) {
			int x = m_index % m_board.width;
			int y = m_index / m_board.width;
			int flags = m_board.getExistFlags(x, y);
			m_index++;
			if (flags != 0) {
				return new Pnt(x, y);
			}
		}
		return null;
	}

	public Pnt navigateUnvisitedEdgeFrom(Pnt p, int trackNumber) {
		int i = m_board.getLinearIndex(p.x, p.y);
		int flags = m_board.getExistFlags(p.x, p.y);
		List<Direction> ds = FlagHelper.getDirectionsForFlags(flags & ~m_visitFlags[i]);
		if (ds.size() == 0) {
			return null;
		}
		
		Direction d = ds.get(0);
		m_visitFlags[i] |= FlagHelper.getDirectionMask(d);
		int j = i + m_board.getLinearIndex(d.v.dx, d.v.dy);
		m_visitFlags[j] |= FlagHelper.getDirectionMask(d.inv());
		return p.add(d.v);
	}

}
